/**
 * Created by yuris on 20.12.14.
 */
package controller {

import flash.geom.Point;
import flash.geom.Point;

import messages.ControllerMessage;

import model.RuntimeProxy;

import model.objects.ShopObjectData;
import model.objects.ShopperData;

import mvcexpress.mvc.PooledCommand;

public class OnSecondPassedCommand extends PooledCommand {
    [Inject]
    public var runtumeProxy:RuntimeProxy;

    private var _bufTime:int;
    public function execute(param:Object):void {
        runtumeProxy.currentTime ++;
        this._bufTime = runtumeProxy.currentTime;
        //sendMessage(ControllerMessage.ONE_SECOND_TIMER, {time:runtumeProxy.currentTime});

        runtumeProxy.warehouseData.currentTime = this._bufTime;
        this._controlShoppersEmission();
        this._controlDoors();
        runtumeProxy.DEBUG_visualizeOccPoints();

    }

    private var _shopperDataBuf:ShopperData
    private var _activeShoppersNum:int = 0;

    private var _doorPoints:Vector.<Point>;
    private function _controlDoors():void {
        var i:int = 0;
        this._doorPoints = runtumeProxy.shopDesign.getDoorPoints();
        for (i = 0; i < this._doorPoints.length; i++) {
            runtumeProxy.setDoorState(this._doorPoints[i], false);
        }
        for (i = 0; i < runtumeProxy.shoppersPool.length; i++) {
            this._shopperDataBuf = runtumeProxy.shoppersPool[i];
            if(this._shopperDataBuf.isActive){
                if(this._shopperDataBuf.position.y == 0 || this._shopperDataBuf.position.y == -1){
                    if(this.runtumeProxy.shopDesign.getDoorAtX(this._shopperDataBuf.position.x) != null){
                        runtumeProxy.setDoorState(new Point(this._shopperDataBuf.position.x,0), true);
                    }
                } else if(this._shopperDataBuf.position.x == 0 || this._shopperDataBuf.position.x == -1){
                    if(this.runtumeProxy.shopDesign.getDoorAtY(this._shopperDataBuf.position.y) != null){
                        runtumeProxy.setDoorState(new Point(0,this._shopperDataBuf.position.y), true);
                    }
                }
            }
        }

    }



    private function _controlShoppersEmission():void {
        this._activeShoppersNum = runtumeProxy.activeShoppersNum;
        if(this._activeShoppersNum == 0 || Math.random() < 0.2){
            if(this._activeShoppersNum < 1){
                this._shopperDataBuf = runtumeProxy.getUnusedShopperData();
                var _shopperPath:Vector.<Point> = this._getPath();
                this._shopperDataBuf.path = _shopperPath;
                this._shopperDataBuf.position = _shopperPath[0];
                this._shopperDataBuf.angle = ShopObjectData.getAngleByVector(_shopperPath[1].subtract(_shopperPath[0]))
                this._shopperDataBuf.isActive = true;
            }
        }
    }

    private function _getPath():Vector.<Point> {
        var _path:Vector.<Point> = new <Point>[];
        var _spawnPoint:Point;

        //spawn point
        //--------------------------
        if(Math.random() < 0.5){
            _spawnPoint = new Point(runtumeProxy.shopDesign.sizeX, -1 );
        } else {
            _spawnPoint = new Point(-1, runtumeProxy.shopDesign.sizeY );
        }
        _path.push(_spawnPoint);


        //door entry point
        //---------------------------
        var _doorPoint:Point = this._getNearestDoorPoint(_spawnPoint);
        _path.push(_doorPoint);

        //shopping
        //--------------------------
        var _shelfs:Vector.<ShopObjectData> = runtumeProxy.selectShelfs();
        if(_shelfs.length > 0){
            var _visitedShelfsNum:int = int(Math.random()*4) + 2;
            var _bufShelfData:ShopObjectData = null;
            for (var i:int = 0; i < _shelfs.length; i++) {
                _bufShelfData = this._takeRandomShelf(_shelfs);
                if(_bufShelfData == null){
                    break;
                } else {
                    _path.push(runtumeProxy.getShelfClientPoint(_bufShelfData));
                }
            }
        }

        //cash desk point
        //--------------------------
        var _nearestCashDeskData:ShopObjectData = this._getNearestCashDesk(_path[_path.length - 1]);
        var _cashDeskClientPoint:Point = runtumeProxy.getCashDeskClientPoint( _nearestCashDeskData);
        _path.push(_cashDeskClientPoint);


        //door exit point
        //----------------------
        var _doorExitPoint:Point = this._getNearestDoorPoint(_path[_path.length - 1]);
        _path.push(_doorExitPoint);

        //leave view point
        //----------------------
        var _exit1Point:Point = new Point(runtumeProxy.shopDesign.sizeX, -2 );
        var _exit2Point:Point = new Point(-2, runtumeProxy.shopDesign.sizeY);
        if(Point.distance(_doorExitPoint, _exit1Point) < Point.distance(_doorExitPoint, _exit2Point)){
            _path.push(_exit1Point);
        } else {
            _path.push(_exit2Point);
        }


        return _path
    }

    private function _getNearestDoorPoint(targetPoint:Point):Point {
        var _doorPoints:Vector.<Point> = runtumeProxy.shopDesign.getDoorPoints();
        var  _result:Point = _doorPoints[0];
        var _distanceMin:Number = Point.distance(_result,targetPoint);
        var _distanceBuf:Number = 0;
        for (var i:int = 0; i < _doorPoints.length; i++) {
            var object:Object = _doorPoints[i];
            _distanceBuf = Point.distance(_doorPoints[i],targetPoint);
            if(_distanceBuf < _distanceMin){
                _distanceMin = _distanceBuf;
                _result = _doorPoints[i];
            }
        }
        return _result;
    }

    private function _getNearestCashDesk(targetPoint:Point):ShopObjectData {
        var _cashDesks:Vector.<ShopObjectData> = runtumeProxy.selectCashDesks();
        var  _nearestCashDesk:ShopObjectData = _cashDesks[0];
        var _distanceMin:Number = Point.distance(_nearestCashDesk.position,targetPoint);
        var _distanceBuf:Number = 0;
        for (var i:int = 0; i < _cashDesks.length; i++) {
            _distanceBuf = Point.distance(_cashDesks[i].position, targetPoint);
            if(_distanceBuf < _distanceMin){
                _distanceMin = _distanceBuf;
                _nearestCashDesk = _cashDesks[i];
            }
        }
        return _nearestCashDesk;
    }


    private function _takeRandomShelf(shelfs:Vector.<ShopObjectData>):ShopObjectData {
        if(shelfs.length == 0){
            return null;
        }
        var i:int = int(Math.random() * shelfs.length);
        var _result:ShopObjectData = shelfs[i];
        shelfs.splice(i,1);

        return _result;
    }


}
}
